#include <iostream>
#include <map>
#include <vector>
#include <utility>
#include <string>

using std::cout;
using std::endl;
using std::map;
using std::vector;
using std::pair;
using std::string;
using std::make_pair;

template <typename Container>
void display(const Container &con)
{
    for(auto &elem : con)
    {
        cout << elem.first 
             << "  " << elem.second << endl;
    }
}

void test()
{
    //map的特征
    //1、map中存放的是key-value类型，也就是pair类型
    //key值是唯一的，不能重复，但是value值是可以重复的
    //2、默认情况会按照key值进行升序排列
    //3、底层使用红黑树
    map<int, string> number = {
        //1、直接使用pair
        pair<int, string>(1, "beijing"),
        pair<int, string>(3, "nanjing"),
        //2、使用大括号的形式
        {6, "hubei"},
        {8, "wuhan"},
        //3、make_pair函数的返回类型就是pair
        make_pair(2, "beijing"),
        make_pair(7, "wuhan"),
        make_pair(1, "beijing")
    };
    display(number);

    cout << endl << "map的查找操作" << endl;
    size_t cnt1 = number.count(8);
    cout << "cnt1 = " << cnt1 << endl;

    map<int, string>::iterator it = number.find(6);
    if(it != number.end())
    {
        cout << "该元素存在map中 "
             << it->first << " " << it->second << endl;
    }
    else
    {
        cout << "该元素不在map中" << endl;
    }

    cout << endl << "map的插入操作" << endl;
    pair<map<int, string>::iterator, bool> ret = 
        /* number.insert(pair<int, string>(5, "dongjing")); */
        /* number.insert({5, "dongjing"}); */
        number.insert(make_pair(5, "dongjing"));
    if(ret.second)
    {
        cout << "插入成功 " << ret.first->first << " "
             << ret.first->second << endl;
    }
    else
    {
        cout << "插入失败,该元素存在map中" << endl;
    }
    display(number);

    cout << endl << endl;
    number.insert({{4, "wuhan"}, {5, "wangdao"}});
    display(number);

    cout << endl << "map中的下标操作" << endl;
    cout << "number[3] = " << number[3] << endl;//查找
    cout << "number[15] = " << number[15] << endl;//插入
    display(number);

    cout << endl << endl;
    /* T &operator[](const Key &); */
    number.operator[](15).operator=("wangdao");
    /* number[15] = "wangdao";//修改 */
    number[2] = "wangdao";
    display(number);

}

class Compare
{
public:
    int operator()(int x, int y)
    {
        return x + y;
    }
};

void test00()
{
    Compare com;
    /* com(1, 2); */
    com.operator()(1, 2);
}

int main(int argc, char **argv)
{
    test();
    return 0;
}

